﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Collections;
using System.Xml;
using Reborn_WorldServer.PendingClients;
using System.IO;
using App1AppHandler;
using Reborn_WorldServer.PendingClusterQuerys;

namespace Reborn_WorldServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            instance = this;
            InitializeComponent();
            GetIP();
        }

        public static Form1 instance;

        private Socket socketClientConnect;
        private bool socketClientConnectListening = false;

        private System.Collections.ArrayList clientSockets =
                ArrayList.Synchronized(new System.Collections.ArrayList());

        private void Button_ConnectPrimary_Click(object sender, EventArgs e)
        {
            // See if we have text on the IP and Port text fields
            if (TextBox_PrimaryIP.Text == "" || TextBox_PrimaryPort.Text == "")
            {
                MessageBox.Show("IP Address and Port Number are required to connect to the Server\n");
                return;
            }

            try
            {
                // Create the socket instance
                Socket primarySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                Managers.socketPrimary = new ServerSocketData(primarySocket);

                // Cet the remote IP address
                IPAddress ip = IPAddress.Parse(TextBox_PrimaryIP.Text);
                int iPortNo = System.Convert.ToInt16(TextBox_PrimaryPort.Text);
                // Create the end point 
                IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo);
                // Connect to the remote host
                Managers.socketPrimary.socket.Connect(ipEnd);
                if (Managers.socketPrimary.socket.Connected)
                {
                    this.Invoke((Action)updateControls);

                    //Wait for data asynchronously 
                    WaitForServerData();

                    byte[] byData = System.Text.Encoding.ASCII.GetBytes("<clientport portnumber=\"" + TextBox_ServerPort.Text + "\" />" + "\0");
                    Managers.socketPrimary.socket.Send(byData);

                    Managers.localWorldsManager.sendWorldsToPrimary();
                }
            }
            catch (SocketException se)
            {
                string str;
                str = "\nConnection failed, is the server running?\n" + se.Message;
                MessageBox.Show(str);
                this.Invoke((Action)updateControls);
            }		
        }

        public void updateControls()
        {
            if (Managers.socketPrimary != null && Managers.socketPrimary.socket.Connected)
            {
                Button_ConnectPrimary.Enabled = false;
                Button_DisconectPrimary.Enabled = true;

                TextBox_PrimaryIP.Enabled = false;
                TextBox_PrimaryPort.Enabled = false;
            }
            else
            {
                Button_DisconectPrimary.Enabled = false;

                if (socketClientConnectListening)
                {
                    Button_ConnectPrimary.Enabled = true;

                    TextBox_PrimaryIP.Enabled = true;
                    TextBox_PrimaryPort.Enabled = true;
                }
                else
                {
                    Button_ConnectPrimary.Enabled = false;

                    TextBox_PrimaryIP.Enabled = false;
                    TextBox_PrimaryPort.Enabled = false;
                }
            }

            lock (clientSockets)
            {
                Label_ClientConnections.Text = clientSockets.Count.ToString();
            }

            if (socketClientConnectListening)
            {
                this.Button_StartClientListening.Enabled = false;
                this.Button_StopClientListening.Enabled = true;
            }
            else
            {
                this.Button_StartClientListening.Enabled = true;
                this.Button_StopClientListening.Enabled = false;
            }
        }

        // Start waiting for data from the server
        public void WaitForServerData()
        {
            Managers.socketPrimary.dataBuffer = new byte[1024];

            //socketPacket is just an object that gets passed around with the AsyncCalls 
            //to let us determine which client is sending us data
            IAsyncResult result = Managers.socketPrimary.socket.BeginReceive(Managers.socketPrimary.dataBuffer, 0, Managers.socketPrimary.dataBuffer.Length,
                SocketFlags.None, new AsyncCallback(OnServerDataReceived), Managers.socketPrimary);
        }

        // Start waiting for data from the client
        public void WaitForClientData(ClientSocketData clientSocketData)
        {
            try
            {
                clientSocketData.dataBuffer = new byte[1024];

                //socketPacket is just an object that gets passed around with the AsyncCalls 
                //to let us determine which client is sending us data
                clientSocketData.socket.BeginReceive(clientSocketData.dataBuffer, 0, clientSocketData.dataBuffer.Length,
                    SocketFlags.None, new AsyncCallback(onClientDataRecieved), clientSocketData);
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }

        public void OnServerDataReceived(IAsyncResult asyn)
        {
            ServerSocketData socketPacket = (ServerSocketData)asyn.AsyncState;
            string allData = "";
            try
            {
                //Get Number of chars written to socket
                int iRx = socketPacket.socket.EndReceive(asyn);
                //Create char array to hold data
                char[] chars = new char[iRx];
                // Extract the characters as a buffer
                Decoder d = Encoding.UTF8.GetDecoder();
                d.GetChars(socketPacket.dataBuffer, 0, iRx, chars, 0);
                // Put data into string
                String szData = new String(chars);

                while (socketPacket.socket.Available > 0)
                {
                    byte[] buffer = new byte[1024];
                    iRx = socketPacket.socket.Receive(buffer);
                    chars = new char[iRx];

                    d.GetChars(buffer, 0, iRx, chars, 0);
                    szData = szData + new String(chars);
                }

                //Server Disconnect
                if (szData == "")
                {
                    closeServerSocket();
                    return;
                }

                socketPacket.AppendData(szData);

                allData = socketPacket.getRawData();

                string message = socketPacket.getMessage();
                while (message != "")
                {
                    XmlDocument xml = new XmlDocument();
                    xml.LoadXml(message);

                    //Process Data
                    if (xml.FirstChild.Name == "clientexists")
                    {
                        int userid = int.Parse(xml.FirstChild.Attributes["userid"].Value.ToString());
                        string clientid = xml.FirstChild.Attributes["clientid"].Value.ToString();

                        bool userExists = false;
                        if (Managers.pendingClientsManager.clientExists(userid) || Managers.characterManager.characterExists(userid))
                            userExists = true;

                        bool clientExists = false;
                        if (userExists == false)
                        {
                            if (Managers.characterManager.clientExists(clientid))
                                clientExists = true;
                        }

                        string result = "notfound";
                        if (clientExists)
                            result = "clientfound";
                        else if (userExists)
                            result = "userfound";

                        byte[] byData = System.Text.Encoding.ASCII.GetBytes("<clientexists_result userid=\"" + userid.ToString() + "\" result=\"" + result + "\" />" + "\0");
                        Managers.socketPrimary.socket.BeginSend(byData, 0, byData.Length, SocketFlags.None, null, null);
                    }
                    else if (xml.FirstChild.Name == "ownedworlds")
                    {
                        Managers.localWorldsManager.updateWorldsFromXML(message);
                    }
                    else if (xml.FirstChild.Name == "addpendingclient")
                    {
                        int userid = int.Parse(xml.FirstChild.Attributes["userid"].Value.ToString());
                        int characterid = int.Parse(xml.FirstChild.Attributes["characterid"].Value.ToString());
                        string uid = xml.FirstChild.Attributes["uid"].Value.ToString();
                        int mapid = int.Parse(xml.FirstChild.Attributes["mapid"].Value.ToString());
                        int instance = int.Parse(xml.FirstChild.Attributes["instance"].Value.ToString());
                        int mapx = int.Parse(xml.FirstChild.Attributes["mapx"].Value.ToString());
                        int mapy = int.Parse(xml.FirstChild.Attributes["mapy"].Value.ToString());

                        bool result = Managers.pendingClientsManager.AddPendingClient(userid, characterid, uid, mapid, instance, mapx, mapy, false);

                        byte[] byData = System.Text.Encoding.ASCII.GetBytes("<pendingclient_result userid=\"" + userid.ToString() + "\" result=\"" + result.ToString() + "\" />" + "\0");
                        Managers.socketPrimary.socket.BeginSend(byData, 0, byData.Length, SocketFlags.None, null, null);
                    }
                    else if (xml.FirstChild.Name == "addtransferclient")
                    {
                        int userid = int.Parse(xml.FirstChild.Attributes["userid"].Value.ToString());
                        int characterid = int.Parse(xml.FirstChild.Attributes["characterid"].Value.ToString());
                        string uid = xml.FirstChild.Attributes["uid"].Value.ToString();
                        int mapid = int.Parse(xml.FirstChild.Attributes["mapid"].Value.ToString());
                        int instance = int.Parse(xml.FirstChild.Attributes["instance"].Value.ToString());
                        int mapx = int.Parse(xml.FirstChild.Attributes["mapx"].Value.ToString());
                        int mapy = int.Parse(xml.FirstChild.Attributes["mapy"].Value.ToString());

                        bool result = Managers.pendingClientsManager.AddPendingClient(userid, characterid, uid, mapid, instance, mapx, mapy, true);

                        Managers.BeginSendToPrimary("<transferclient_result userid=\"" + userid.ToString() + "\" result=\"" + result.ToString() + "\" />");
                    }
                    else if (xml.FirstChild.Name == "transfercharacter_result")
                    {
                        int userid = int.Parse(xml.FirstChild.Attributes["userid"].Value.ToString());
                        string error = xml.FirstChild.Attributes["error"].Value.ToString();
                        string uid = xml.FirstChild.Attributes["uid"].Value.ToString();
                        int port = int.Parse(xml.FirstChild.Attributes["port"].Value.ToString());

                        Managers.transferCharacterManager.ProcessTransferCharacterResult(userid, error, uid, port);
                    }
                    else if (xml.FirstChild.Name == "tellrequestPS")
                    {
                        string tellguid = xml.FirstChild.Attributes["tellguid"].Value.ToString();
                        string fromname = xml.FirstChild.Attributes["fromname"].Value.ToString();
                        string toname = xml.FirstChild.Attributes["toname"].Value.ToString();
                        
                        string msg = xml.FirstChild["txt"].InnerText;
                        string itemlinksxml = xml.FirstChild["itemlinks"].OuterXml;

                        msg = fromname + " tells you: " + msg;

                        bool result = Managers.GameHandler.TrySendMessage(toname, msg, itemlinksxml, "tell");

                        StringWriter stringWriter = new StringWriter();
                        XmlTextWriter xmldoc = new XmlTextWriter(stringWriter);
                        xmldoc.WriteStartElement("tellrequestresultPS");

                        xmldoc.WriteAttributeString("tellguid", tellguid.ToString());
                        xmldoc.WriteAttributeString("fromname", fromname.ToString());
                        xmldoc.WriteAttributeString("toname", toname.ToString());
                        xmldoc.WriteAttributeString("messagesuccessfull", result.ToString());

                        xmldoc.WriteEndElement();
                        xmldoc.Flush();
                        xmldoc.Close();
                        stringWriter.Flush();
                        string xmlMessage = stringWriter.ToString();

                        Managers.BeginSendToPrimary(xmlMessage);
                    }
                    else if (xml.FirstChild.Name == "tellrequestresultWS")
                    {
                        string tellguid = xml.FirstChild.Attributes["tellguid"].Value.ToString();
                        string fromname = xml.FirstChild.Attributes["fromname"].Value.ToString();
                        string toname = xml.FirstChild.Attributes["toname"].Value.ToString();
                        bool msgSuccess = bool.Parse(xml.FirstChild.Attributes["messagesuccessfull"].Value.ToString());

                        Managers.tellManager.processResult(msgSuccess, tellguid, fromname, toname);
                    }
                    else if (xml.FirstChild.Name == "karmanotification")
                    {
                        int charId = int.Parse(xml.FirstChild.Attributes["characterid"].Value.ToString());
                        Managers.characterManager.recieveKarmaNotification(charId);
                    }
                    else if (xml.FirstChild.Name == "newmail")
                    {
                        int characterId = int.Parse(xml.FirstChild.Attributes["characterid"].Value.ToString());

                        Managers.characterManager.recieveNewMail(characterId);
                    }
                    else if (xml.FirstChild.Name == "sendchanneljoin")
                    {
                        string channel = xml.FirstChild.Attributes["channel"].Value.ToString();
                        string from = xml.FirstChild.Attributes["from"].Value.ToString();

                        Managers.characterManager.recieveJoinChannelNotification(channel, from);
                    }
                    else if (xml.FirstChild.Name == "sendchannelleave")
                    {
                        string channel = xml.FirstChild.Attributes["channel"].Value.ToString();
                        string from = xml.FirstChild.Attributes["from"].Value.ToString();

                        Managers.characterManager.recieveLeaveChannelNotification(channel, from);
                    }
                    else if (xml.FirstChild.Name == "sendchannelmessage")
                    {
                        string channel = xml.FirstChild.Attributes["channel"].Value.ToString();
                        string from = xml.FirstChild.Attributes["from"].Value.ToString();

                        string msg = xml["sendchannelmessage"]["txt"].InnerText;
                        string itemlinks = xml["sendchannelmessage"]["itemlinks"].OuterXml;

                        Managers.characterManager.recieveChannelMessage(channel, from, msg, itemlinks);
                    }
                    else if (xml.FirstChild.Name == "globalmessage")
                    {
                        string gmessage = xml["globalmessage"]["txt"].InnerText;
                        string glinks = xml["globalmessage"]["itemlinks"].OuterXml;

                        Managers.characterManager.sendServerWideMessage(gmessage, glinks);
                    }
                    else if (xml.FirstChild.Name == "globalwhorequest")
                    {
                        int characterId = int.Parse(xml.FirstChild.Attributes["characterid"].Value.ToString());
                        List<string> charactersOnline = Managers.characterManager.getCharactersOnServer();

                        StringWriter stringWriter = new StringWriter();
                        XmlTextWriter xmldoc = new XmlTextWriter(stringWriter);
                        xmldoc.WriteStartElement("globalwhoresult");

                        xmldoc.WriteAttributeString("characterid", characterId.ToString());

                        foreach (string str in charactersOnline)
                        {
                            xmldoc.WriteStartElement("characteronline");
                            xmldoc.WriteString(str);
                            xmldoc.WriteEndElement();
                        }

                        xmldoc.WriteEndElement();
                        xmldoc.Flush();
                        xmldoc.Close();
                        stringWriter.Flush();
                        string xmlMessage = stringWriter.ToString();

                        Managers.BeginSendToPrimary(xmlMessage);
                    }
                    else if (xml.FirstChild.Name == "globalwhoresult")
                    {
                        int characterId = int.Parse(xml.FirstChild.Attributes["characterid"].Value.ToString());
                        string xmlMessage = xml.InnerXml;
                        Managers.pendingQueryManager.processWhoResult(characterId, xmlMessage);
                    }
                    else if (xml.FirstChild.Name == "friendonline")
                    {
                        int charId = int.Parse(xml.FirstChild.Attributes["id"].Value.ToString());

                        Managers.characterManager.recieveFriendOnline(charId);
                    }
                    else if (xml.FirstChild.Name == "friendoffline")
                    {
                        int charId = int.Parse(xml.FirstChild.Attributes["id"].Value.ToString());

                        Managers.characterManager.recieveFriendOffline(charId);
                    }
                    //Primary server requests us to look for friend info on supplied character Ids
                    else if (xml.FirstChild.Name == "findfriendsPS")
                    {
                        //The Id of the character thats looking up friends. We need to pass this back to primary
                        int charId = int.Parse(xml.FirstChild.Attributes["friendsofId"].Value.ToString());

                        //Get list of friend IDs we need to locate their name, instanceID, and MapID if they exist here
                        List<int> friendIdsToFind = new List<int>();
                        StringReader sr = new StringReader(message);
                        XmlTextReader xmlReader = new XmlTextReader(sr);
                        while (xmlReader.Read())
                        {
                            if (xmlReader.Name == "friend")
                                friendIdsToFind.Add(int.Parse(xmlReader.GetAttribute("id").ToString()));
                        }

                        //Attempt to locate requested IDs, send any located players back to primary
                        StringWriter stringWriter = new StringWriter();
                        XmlTextWriter xmldoc = new XmlTextWriter(stringWriter);
                        xmldoc.WriteStartElement("findfriendsPS");
                        xmldoc.WriteAttributeString("friendsofId", charId.ToString());
                        foreach (int friendId in friendIdsToFind)
                        {
                            Character foundCharacter = Managers.characterManager.getCharacter(friendId);
                            if (foundCharacter != null)
                            {
                                xmldoc.WriteStartElement("frienddata");
                                xmldoc.WriteAttributeString("id", foundCharacter.ID.ToString());
                                xmldoc.WriteAttributeString("name", foundCharacter.Name);
                                xmldoc.WriteAttributeString("instance", foundCharacter.Instance.ToString());
                                xmldoc.WriteAttributeString("mapid", foundCharacter.MapID.ToString());
                                xmldoc.WriteEndElement();
                            }
                        }
                        xmldoc.WriteEndElement();
                        xmldoc.Flush();
                        xmldoc.Close();
                        stringWriter.Flush();
                        string xmlMessage = stringWriter.ToString();

                        Managers.BeginSendToPrimary(xmlMessage);
                    }
                    //Find friends complete. This is the result from the primary after it has queried all the other world servers
                    else if (xml.FirstChild.Name == "findfriendsresultWS")
                    {
                        int charId = int.Parse(xml.FirstChild.Attributes["friendsofId"].Value.ToString());

                        Character foundCharacter = Managers.characterManager.getCharacter(charId);

                        if (foundCharacter != null)
                            foundCharacter.friendsManager.processFriendDataFromPrimary(message);
                    }
                    

                    message = socketPacket.getMessage();
                }

                //Go back to listening
                WaitForServerData();
            }
            catch
            {
                closeServerSocket();
            }
        }
        public void closeClientSocket(ClientSocketData clientSocketData)
        {
            if (clientSocketData == null)
                return;

            lock (clientSockets)
            {
                clientSockets.Remove(clientSocketData);
            }

            try
            {
                if (clientSocketData.socket.Connected)
                    clientSocketData.socket.Close();

                clientSocketData.killTimeout();

                if (clientSocketData._character != null)
                    Managers.GameHandler.AppDisconnect(clientSocketData);
            }
            catch { }

            this.Invoke((Action)updateControls);
        }
        private void onClientDataRecieved(IAsyncResult asyn)
        {
            ClientSocketData socketPacket = null;
            try
            {
                socketPacket = (ClientSocketData)asyn.AsyncState;

                //Get Number of chars written to socket
                int iRx = socketPacket.socket.EndReceive(asyn);
                //Create char array to hold data
                char[] chars = new char[iRx];
                // Extract the characters as a buffer
                Decoder d = Encoding.UTF8.GetDecoder();
                d.GetChars(socketPacket.dataBuffer, 0, iRx, chars, 0);
                // Put data into string
                String szData = new String(chars);

                while (socketPacket.socket.Available > 0)
                {
                    byte[] buffer = new byte[1024];
                    iRx = socketPacket.socket.Receive(buffer);
                    chars = new char[iRx];

                    d.GetChars(buffer, 0, iRx, chars, 0);
                    szData = szData + new String(chars);
                }

                //Client Disconnect
                if (szData == "\0" || szData == "\0\0" || szData == "")
                {
                    closeClientSocket(socketPacket);
                    return;
                }

                socketPacket.AppendData(szData);

                string clientMessage = socketPacket.getMessage();
                while (clientMessage != "")
                {
                    XmlDocument xml = new XmlDocument();
                    xml.LoadXml(clientMessage);

                    if (xml.FirstChild.Name == "clientdata")
                    {
                        int userid = int.Parse(xml.FirstChild.Attributes["userid"].Value.ToString());
                        string uid = xml.FirstChild.Attributes["uid"].Value.ToString();
                        string clientversion = tryGetClientVersion(xml);
                        string clientid = xml.FirstChild.Attributes["clientid"].Value.ToString();

                        socketPacket.killTimeout();

                        PendingClient pendingClient = Managers.pendingClientsManager.GetPendingClient(userid);
                        if (pendingClient == null || pendingClient.uid != uid)
                        {
                            closeClientSocket(socketPacket);
                            return;
                        }

                        //If remove fails, we have 2 threads trying to enter the same character, close one of them
                        if (Managers.pendingClientsManager.RemovePendingClient(pendingClient) == false)
                            closeClientSocket(socketPacket);

                        socketPacket.clientId = clientid;

                        //Sets the characters socket data
                        socketPacket.succesfullyEntered = Managers.GameHandler.EnterGame(socketPacket, pendingClient.userID, pendingClient.characterID, pendingClient.mapID, pendingClient.instance, pendingClient.mapX, pendingClient.mapY, pendingClient.isTransfer, clientversion);

                        // Send back the reply to the client
                        string replyMsg = "<clientdata_result />";

                        socketPacket.socket.BeginSend(replyMsg);

                        if (socketPacket._character.showTips == true && pendingClient.isTransfer == false)
                        {
                            socketPacket.socket.BeginSend("<showtips />");
                        }

                        //Go back to listening
                        WaitForClientData(socketPacket);
                        return;
                    }

                    //Disconnect the socket if user is not logged in, but is sending data
                    if (socketPacket._character == null)
                    {
                        closeClientSocket(socketPacket);
                        return;
                    }

                    if (xml.FirstChild.Name == "exitgame")
                    {
                        string result = Managers.GameHandler.ExitGame(socketPacket._character);
                        string replyMsg = "<exitgame_result>" + result + "</exitgame_result>";

                        socketPacket.socket.BeginSend(replyMsg, false, bool.Parse(result));
                        
                    }
                    else if (xml.FirstChild.Name == "changeposition")
                    {
                        List<string> moves = new List<string>();
                        int creatureID = -1;
                        foreach (XmlNode node in xml.FirstChild.ChildNodes)
                        {
                            if (node.Name == "move")
                                moves.Add(node.InnerText);
                            if (node.Name == "creatureid")
                                creatureID = int.Parse(node.InnerText);
                        }
                        string result = Managers.GameHandler.ChangePosition(socketPacket._character, moves, creatureID);

                        if (result != "")
                        {
                            string replyMsg = "<changeposition_result>" + result + "</changeposition_result>";

                            socketPacket.socket.BeginSend(replyMsg);
                        }
                    }
                    else if (xml.FirstChild.Name == "busylog")
                    {
                        socketPacket._character.SendMessage("Last Server ID: " + socketPacket._character.getBusyId().ToString(), "");
                    }
                    else if (xml.FirstChild.Name == "tips")
                    {
                        bool show = bool.Parse(xml.FirstChild.Attributes["show"].Value.ToString());
                        socketPacket._character.showTips = show;
                    }
                    else if (xml.FirstChild.Name == "joinchannel")
                    {
                        string channelid = xml.FirstChild.Attributes["id"].Value.ToString();
                        socketPacket._character.chatChannelManager.joinChannel(channelid);
                    }
                    else if (xml.FirstChild.Name == "leavechannel")
                    {
                        string channelid = xml.FirstChild.Attributes["id"].Value.ToString();
                        socketPacket._character.chatChannelManager.leaveChannel(channelid);
                    }
                    else if (xml.FirstChild.Name == "selfbind")
                    {
                        Managers.GameHandler.SelfBind(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "useportal")
                    {
                        int mapx = int.Parse(xml.FirstChild.Attributes["mapx"].Value.ToString());
                        int mapy = int.Parse(xml.FirstChild.Attributes["mapy"].Value.ToString());

                        string result = Managers.GameHandler.UsePortal(socketPacket._character, mapx, mapy);

                        //Empty result means we're waiting on a different server
                        if (result != "")
                        {
                            string replyMsg = "<useportal_result>" + result + "</useportal_result>";

                            socketPacket.socket.BeginSend(replyMsg);
                        }
                    }
                    else if (xml.FirstChild.Name == "random")
                    {
                        Managers.GameHandler.randomRoll(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "userInputChoice")
                    {
                        string choice = xml.FirstChild.Attributes["choice"].Value.ToString();
                        long id = long.Parse(xml.FirstChild.Attributes["id"].Value.ToString());

                        socketPacket._character.processPendingInputResult(id, choice);
                    }
                    else if (xml.FirstChild.Name == "moveitem")
                    {
                        int gameuid = int.Parse(xml.FirstChild.Attributes["gameuid"].Value.ToString());
                        string source = xml.FirstChild.Attributes["source"].Value.ToString();
                        int sourcex = int.Parse(xml.FirstChild.Attributes["sourcex"].Value.ToString());
                        int sourcey = int.Parse(xml.FirstChild.Attributes["sourcey"].Value.ToString());
                        string destination = xml.FirstChild.Attributes["destination"].Value.ToString();
                        int destinationx = int.Parse(xml.FirstChild.Attributes["destinationx"].Value.ToString());
                        int destinationy = int.Parse(xml.FirstChild.Attributes["destinationy"].Value.ToString());
                        int pageNumber = int.Parse(xml.FirstChild.Attributes["pagenumber"].Value.ToString());

                        string result = Managers.GameHandler.MoveItem(socketPacket._character, gameuid, source, sourcex, sourcey, destination, destinationx, destinationy, pageNumber);

                        if (result == "false")
                        {
                            socketPacket.socket.BeginSend("<moveitem_result>false</moveitem_result>");
                        }
                        else if (result != "noResult")
                        {
                            socketPacket.socket.BeginSend(result);
                        }
                    }
                    else if (xml.FirstChild.Name == "movespell")
                    {
                        int sourcepagenumber = int.Parse(xml.FirstChild.Attributes["sourcepagenumber"].Value.ToString());
                        int sourceindex = int.Parse(xml.FirstChild.Attributes["sourceindex"].Value.ToString());
                        int destpagenumber = int.Parse(xml.FirstChild.Attributes["destpagenumber"].Value.ToString());
                        int destindex = int.Parse(xml.FirstChild.Attributes["destindex"].Value.ToString());

                        string result = Managers.GameHandler.MoveSpell(socketPacket._character, sourcepagenumber, sourceindex, destpagenumber, destindex);

                        string replyMsg = "<movespell_result>" + result + "</movespell_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "gettradeskilldata")
                    {
                        string tradetype = xml.FirstChild.Attributes["tradetype"].Value.ToString();

                        socketPacket._character.recipieManager.getTradeSkillData(tradetype, true);
                    }
                    else if (xml.FirstChild.Name == "getmail")
                    {
                        socketPacket._character.getMailBox(true);
                    }
                    else if (xml.FirstChild.Name == "sendmaildata")
                    {
                        string toCharacterName = xml.FirstChild.Attributes["tocharactername"].Value.ToString();
                        int coins = int.Parse(xml.FirstChild.Attributes["coins"].Value.ToString());
                        string subject = xml.FirstChild.ChildNodes[0].InnerText;
                        string message = xml.FirstChild.ChildNodes[1].InnerText;

                        List<long> attachmentGuids = new List<long>();
                        foreach (XmlNode node in xml.FirstChild.ChildNodes[2])
                            attachmentGuids.Add(long.Parse(node.Attributes["guid"].Value.ToString()));

                        Managers.GameHandler.sendMail(socketPacket._character, toCharacterName, subject, message, coins, attachmentGuids);
                    }
                    else if (xml.FirstChild.Name == "deletemail")
                    {
                        int mailId = int.Parse(xml.FirstChild.Attributes["mailid"].Value.ToString());
                        Managers.GameHandler.deleteMail(socketPacket._character, mailId);
                    }
                    else if (xml.FirstChild.Name == "removemail")
                    {
                        int mailId = int.Parse(xml.FirstChild.Attributes["mailid"].Value.ToString());
                        Managers.GameHandler.removeMail(socketPacket._character, mailId);
                    }
                    else if (xml.FirstChild.Name == "friendnosdflag")
                    {
                        bool nosdflag = bool.Parse(xml.FirstChild.Attributes["value"].Value.ToString());
                        int friendId = int.Parse(xml.FirstChild.Attributes["friendId"].Value.ToString()); ;

                        socketPacket._character.friendsManager.updateFriendNoSDFlag(friendId, nosdflag);
                    }
                    else if (xml.FirstChild.Name == "addfriend")
                    {
                        string name = xml.FirstChild.Attributes["name"].Value.ToString();
                        Managers.GameHandler.AddFriend(socketPacket._character, name);
                    }
                    else if (xml.FirstChild.Name == "deletefriend")
                    {
                        int friendid = int.Parse(xml.FirstChild.Attributes["friendid"].Value.ToString());
                        Managers.GameHandler.DeleteFriend(socketPacket._character, friendid);
                    }
                    else if (xml.FirstChild.Name == "findfriends")
                    {
                        socketPacket._character.friendsManager.getFriendData();
                    }
                    else if (xml.FirstChild.Name == "resurrect")
                    {
                        Managers.GameHandler.Resurrect(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "attack")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.AttackCreature(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "openclosedoor")
                    {
                        int mapx = int.Parse(xml.FirstChild.Attributes["mapx"].Value.ToString());
                        int mapy = int.Parse(xml.FirstChild.Attributes["mapy"].Value.ToString());
                        string action = xml.FirstChild.Attributes["action"].Value.ToString();

                        string result = Managers.GameHandler.OpenCloseDoor(socketPacket._character, action, mapx, mapy);

                        string replyMsg = "<openclosedoor_result>" + result + "</openclosedoor_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "corpseroll")
                    {
                        long gameuid = long.Parse(xml.FirstChild.Attributes["gameuid"].Value.ToString());

                        string result = Managers.GameHandler.Corpse_Roll(socketPacket._character, socketPacket._character.MapID, socketPacket._character.Instance, socketPacket._character.MapX, socketPacket._character.MapY, gameuid);

                        string replyMsg = "<corpseroll_result>" + result + "</corpseroll_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "spellwarm")
                    {
                        int spellid = int.Parse(xml.FirstChild.Attributes["spellid"].Value.ToString());

                        string result = Managers.GameHandler.Spell_Warm(socketPacket._character, spellid);

                        string replyMsg = "<spellwarm_result>" + result + "</spellwarm_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "spellcastarea")
                    {
                        List<string> moves = new List<string>();
                        foreach (XmlNode node in xml.FirstChild.ChildNodes)
                        {
                            if (node.Name == "move")
                                moves.Add(node.InnerText);
                        }
                        Managers.GameHandler.Spell_CastArea(socketPacket._character, moves);
                    }
                    else if (xml.FirstChild.Name == "spellcasttarget")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.Spell_CastTarget(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "spellcastself")
                    {
                        string result = Managers.GameHandler.Spell_CastSelf(socketPacket._character);

                        string replyMsg = "<spellcastself_result>" + result + "</spellcastself_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "petchangemotion")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        string motiontype = xml.FirstChild.Attributes["motiontype"].Value.ToString();

                        Managers.GameHandler.Pet_ChangeMotion(creatureid, socketPacket._character, motiontype);

                        string replyMsg = "<petchangemotion_result>" + motiontype + "</petchangemotion_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "petattack")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        long attackcreatureid = long.Parse(xml.FirstChild.Attributes["attackcreatureid"].Value.ToString());

                        Managers.GameHandler.Pet_Attack(creatureid, socketPacket._character, attackcreatureid);

                        string replyMsg = "<petattack_result/>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "petmoveto")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        int mapx = int.Parse(xml.FirstChild.Attributes["mapx"].Value.ToString());
                        int mapy = int.Parse(xml.FirstChild.Attributes["mapy"].Value.ToString());

                        Managers.GameHandler.Pet_MoveTo(creatureid, socketPacket._character, mapx, mapy);

                        string replyMsg = "<petmoveto_result/>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "movecoins")
                    {
                        string source = xml.FirstChild.Attributes["source"].Value.ToString();
                        int sourcex = int.Parse(xml.FirstChild.Attributes["sourcex"].Value.ToString());
                        int sourcey = int.Parse(xml.FirstChild.Attributes["sourcey"].Value.ToString());
                        string destination = xml.FirstChild.Attributes["destination"].Value.ToString();
                        int numcoins = int.Parse(xml.FirstChild.Attributes["numcoins"].Value.ToString());

                        string result = Managers.GameHandler.MoveCoins(socketPacket._character, source, sourcex, sourcey, destination, numcoins);

                        string replyMsg = "<movecoins_result>" + result + "</movecoins_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "banker")
                    {
                        string result = Managers.GameHandler.BankerOpenWindow(socketPacket._character);

                        string replyMsg = "<banker_result>" + result + "</banker_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "depositcoins")
                    {
                        int coins = int.Parse(xml.FirstChild.Attributes["coins"].Value.ToString());

                        string result = Managers.GameHandler.BankerDepositCoins(socketPacket._character, coins);

                        string replyMsg = "<depositcoins_result>" + result + "</depositcoins_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "withdrawcoins")
                    {
                        int coins = int.Parse(xml.FirstChild.Attributes["coins"].Value.ToString());

                        string result = Managers.GameHandler.BankerWithdrawCoins(socketPacket._character, coins);

                        string replyMsg = "<withdrawcoins_result>" + result + "</withdrawcoins_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "deposititem")
                    {
                        long gameuid = long.Parse(xml.FirstChild.Attributes["gameuid"].Value.ToString());

                        string result = Managers.GameHandler.BankerDepositItem(socketPacket._character, gameuid);
                        string replyMsg = "<deposititem_result>" + result + "</deposititem_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "withdrawitem")
                    {
                        long gameuid = long.Parse(xml.FirstChild.Attributes["gameuid"].Value.ToString());

                        string result = Managers.GameHandler.BankerWithdrawItem(socketPacket._character, gameuid);
                        string replyMsg = "<withdrawitem_result>" + result + "</withdrawitem_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "vendor")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.VendorOpenWindow(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "inspectcharacter")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.InspectCharacter(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "getkarma")
                    {
                        socketPacket._character.hateManager.getKarmaData();
                    }
                    else if (xml.FirstChild.Name == "haskarma")
                    {
                        Managers.GameHandler.HasKarma(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "canforgive")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.CanForgive(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "forgive")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.Forgive(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "trademakerequest")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.TradeMakeRequest(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "tradecancel")
                    {
                        bool isBusy = bool.Parse(xml.FirstChild.Attributes["isbusy"].Value.ToString());
                        Managers.GameHandler.TradeCancel(socketPacket._character, isBusy);
                    }
                    else if (xml.FirstChild.Name == "tradeaccept")
                    {
                        Managers.GameHandler.TradeAccept(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "tradeadditem")
                    {
                        long itemguid = long.Parse(xml.FirstChild.Attributes["itemguid"].Value.ToString());
                        Managers.GameHandler.TradeAddItem(socketPacket._character, itemguid);
                    }
                    else if (xml.FirstChild.Name == "traderemoveitem")
                    {
                        long itemguid = long.Parse(xml.FirstChild.Attributes["itemguid"].Value.ToString());
                        Managers.GameHandler.TradeRemoveItem(socketPacket._character, itemguid);
                    }
                    else if (xml.FirstChild.Name == "tradechangecoins")
                    {
                        int numcoins = int.Parse(xml.FirstChild.Attributes["numcoins"].Value.ToString());
                        Managers.GameHandler.TradeChangeCoins(socketPacket._character, numcoins);
                    }
                    else if (xml.FirstChild.Name == "tradeacceptoffer")
                    {
                        Managers.GameHandler.TradeAcceptOffer(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "quest")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.QuestCreatureOpenWindow(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "claimreward")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        int rewardid = int.Parse(xml.FirstChild.Attributes["rewardid"].Value.ToString());
                        Managers.GameHandler.QuestClaimReward(socketPacket._character, creatureid, rewardid);
                    }
                    else if (xml.FirstChild.Name == "acceptquest")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.QuestCreatureAcceptQuest(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "trainer")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        Managers.GameHandler.TrainerOpenWindow(socketPacket._character, creatureid);
                    }
                    else if (xml.FirstChild.Name == "sellitem")
                    {
                        long gameuid = long.Parse(xml.FirstChild.Attributes["gameuid"].Value.ToString());
                        long vendorcreatureid = long.Parse(xml.FirstChild.Attributes["vendorcreatureid"].Value.ToString());

                        Managers.GameHandler.VendorSellItem(socketPacket._character, gameuid, vendorcreatureid);
                    }
                    else if (xml.FirstChild.Name == "removebuff")
                    {
                        long spellid = long.Parse(xml.FirstChild.Attributes["spellid"].Value.ToString());

                        Managers.GameHandler.Spell_RemoveBuff(socketPacket._character, spellid);

                        string replyMsg = "<removebuff_result/>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "buyitem")
                    {
                        long gameuid = long.Parse(xml.FirstChild.Attributes["gameuid"].Value.ToString());
                        long vendorcreatureid = long.Parse(xml.FirstChild.Attributes["vendorcreatureid"].Value.ToString());

                        Managers.GameHandler.VendorBuyVendorItem(socketPacket._character, gameuid, vendorcreatureid);
                    }
                    else if (xml.FirstChild.Name == "trainerbuyspell")
                    {
                        int spellid = int.Parse(xml.FirstChild.Attributes["spellid"].Value.ToString());
                        long trainercreatureid = long.Parse(xml.FirstChild.Attributes["trainercreatureid"].Value.ToString());

                        Managers.GameHandler.TrainerBuySpell(socketPacket._character, spellid, trainercreatureid);
                    }
                    else if (xml.FirstChild.Name == "trainerbuyskill")
                    {
                        int skillid = int.Parse(xml.FirstChild.Attributes["weaponskillid"].Value.ToString());
                        long trainercreatureid = long.Parse(xml.FirstChild.Attributes["trainercreatureid"].Value.ToString());

                        Managers.GameHandler.TrainerBuySkill(socketPacket._character, skillid, trainercreatureid);
                    }
                    else if (xml.FirstChild.Name == "trainertrain")
                    {
                        int coins = int.Parse(xml.FirstChild.Attributes["coins"].Value.ToString());
                        long trainercreatureid = long.Parse(xml.FirstChild.Attributes["trainercreatureid"].Value.ToString());

                        Managers.GameHandler.TrainerTrain(socketPacket._character, coins, trainercreatureid);
                    }
                    else if (xml.FirstChild.Name == "serverwho")
                    {
                        if (socketPacket._character.GM == true)
                            Managers.characterManager.whoServerWide(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "globalwho")
                    {
                        if (socketPacket._character.GM == true)
                            Managers.characterManager.whoGlobal(socketPacket._character);
                    }
                    else if (xml.FirstChild.Name == "serversetlevel")
                    {
                        if (socketPacket._character.GM == true)
                        {
                            decimal level = decimal.Parse(xml.FirstChild.Attributes["level"].Value.ToString());
                            string name = xml.FirstChild.Attributes["name"].Value.ToString();
                            string skill = xml.FirstChild.Attributes["skill"].Value.ToString();

                            Managers.characterManager.setCharacterSkill(name, skill, level);
                        }
                    }
                    else if (xml.FirstChild.Name == "serverconjure")
                    {
                        if (socketPacket._character.GM == true)
                        {
                            int itemid = int.Parse(xml.FirstChild.Attributes["itemid"].Value.ToString());
                            Managers.GameHandler.ConjureItem(socketPacket._character, itemid);
                        }
                    }
                    else if (xml.FirstChild.Name == "serverconjurecoins")
                    {
                        if (socketPacket._character.GM == true)
                        {
                            int coins = int.Parse(xml.FirstChild.Attributes["coins"].Value.ToString());
                            Managers.GameHandler.ConjureCoins(socketPacket._character, coins);
                        }
                    }
                    else if (xml.FirstChild.Name.ToLower() == "serverteleport")
                    {
                        if (socketPacket._character.GM == true)
                        {
                            string charactername = xml.FirstChild.Attributes["charactername"].Value.ToString();
                            int portalmapid = int.Parse(xml.FirstChild.Attributes["portalmapid"].Value.ToString());
                            int portalmapx = int.Parse(xml.FirstChild.Attributes["portalmapx"].Value.ToString());
                            int portalmapy = int.Parse(xml.FirstChild.Attributes["portalmapy"].Value.ToString());

                            Character charToPort = Managers.characterManager.getCharacter(charactername);

                            if (charToPort != null)
                                Managers.GameHandler.Teleport(charToPort, portalmapid, portalmapx, portalmapy);
                        }
                    }
                    else if (xml.FirstChild.Name == "sendchannelmessage")
                    {
                        string channelName = xml.FirstChild.Attributes["channel"].Value.ToString();

                        string message = xml.FirstChild.FirstChild.InnerText;
                        string itemLinksXml = xml["sendchannelmessage"]["itemlinks"].OuterXml;

                        socketPacket._character.chatChannelManager.sendChannelMessage(channelName, message, itemLinksXml);
                    }
                    else if (xml.FirstChild.Name == "sendmessage")
                    {
                        string type = xml.FirstChild.Attributes["Type"].Value.ToString();
                        string message = xml.FirstChild.FirstChild.InnerText;
                        string itemLinksXml = xml["sendmessage"]["itemlinks"].OuterXml;

                        if (type == "tell")
                        {
                            string toName = xml.FirstChild.Attributes["MessageTo"].Value.ToString(); ;
                            Managers.GameHandler.SendTell(socketPacket._character, toName, message, itemLinksXml);
                        }
                        else if (type == "say")
                        {
                            Managers.GameHandler.SendSay(socketPacket._character, message, itemLinksXml);
                        }
                        else if (type == "shout")
                        {
                            Managers.GameHandler.SendShout(socketPacket._character, message, itemLinksXml);
                        }
                        else if (type == "server" && socketPacket._character.GM == true)
                        {
                            Managers.characterManager.sendServerWideMessage(message, itemLinksXml);
                        }
                        else if (type == "global" && socketPacket._character.GM == true)
                        {
                            Managers.characterManager.sendGlobalMessage(message, itemLinksXml);
                        }
                    }
                    else if (xml.FirstChild.Name == "fizzle")
                    {
                        string result = Managers.GameHandler.Spell_Fizzle(socketPacket._character);

                        string replyMsg = "<fizzle_result>" + result + "</fizzle_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "rangeattack")
                    {
                        long gameuid = long.Parse(xml.FirstChild.Attributes["itemguid"].Value.ToString());
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());

                        string result = Managers.GameHandler.RangeAttack(socketPacket._character, creatureid, gameuid);

                        string replyMsg = "<rangeattack_result>" + result + "</rangeattack_result>";

                        socketPacket.socket.BeginSend(replyMsg);
                    }
                    else if (xml.FirstChild.Name == "changecolor")
                    {
                        string color = xml.FirstChild.Attributes["color"].Value.ToString();
                        Managers.GameHandler.ChangeColor(socketPacket._character, color);
                    }
                    else if (xml.FirstChild.Name == "createrecipie")
                    {
                        int id = int.Parse(xml.FirstChild.Attributes["id"].Value.ToString());
                        socketPacket._character.recipieManager.createRecipie(id);
                    }
                    else if (xml.FirstChild.Name == "tradelearn")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        string type = xml.FirstChild.Attributes["type"].Value.ToString();

                        socketPacket._character.recipieManager.learnSkill(type, creatureid);
                    }
                    else if (xml.FirstChild.Name == "tradeforget")
                    {
                        long creatureid = long.Parse(xml.FirstChild.Attributes["creatureid"].Value.ToString());
                        string type = xml.FirstChild.Attributes["type"].Value.ToString();

                        socketPacket._character.recipieManager.forgetSkill(type, creatureid);
                    }
                    else
                    {
                        closeClientSocket(socketPacket);
                        return;
                    }

                    clientMessage = socketPacket.getMessage();
                }
                //Go back to listening
                WaitForClientData(socketPacket);
            }
            catch
            {
                closeClientSocket(socketPacket);
            }
        }

        private void closeServerSocket()
        {
            Managers.socketPrimary.socket.Close();
            this.Invoke((Action)updateControls);
        }

        //This will get the servers IP address.... for now just manually set it
        private void GetIP()
        {
            String strHostName = Dns.GetHostName();

            // Find host by name
            IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);

            List<string> IPAddresses = new List<string>();

            // Grab the first IP addresses
            foreach (IPAddress ipaddress in iphostentry.AddressList)
            {
                IPAddresses.Add(ipaddress.ToString());
            }
            this.ComboBox_ServerIPs.DataSource = IPAddresses;
        }

        private void Button_DisconectPrimary_Click(object sender, EventArgs e)
        {
            closeServerSocket();
        }

        private void Button_StartClientListening_Click(object sender, EventArgs e)
        {
            try
            {
                // Check the port value
                if (this.TextBox_ServerPort.Text == "")
                {
                    MessageBox.Show("Please enter a Port Number");
                    return;
                }
                string portStr = this.TextBox_ServerPort.Text;
                int port = Convert.ToInt32(portStr);

                IPAddress ip = IPAddress.Parse(this.ComboBox_ServerIPs.Text);

                // Create the listening socket...
                socketClientConnect = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


                IPEndPoint ipLocal = new IPEndPoint(ip, port);
                // Bind to local IP Address...
                socketClientConnect.Bind(ipLocal);
                // Start listening...
                socketClientConnect.Listen(32);
                // Create the call back for any client connections...
                socketClientConnect.BeginAccept(new AsyncCallback(OnClientConnect), null);
                
                socketClientConnectListening = true;
                this.Invoke((Action)updateControls);

                //Policy socket (Adobe standard, policy file must be served via xml socket or sandbox error will be thrown)
                //Connection establisted the fastest if policy is served on port 843 (Adobe automatically checkes this port
                //first regardless of IP specified). We will have to wait for the client to fail on this port if we specify a differnt one
                //p_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //IPEndPoint ipLocal_p = new IPEndPoint(IPAddress.Any, 843);
                //p_Socket.Bind(ipLocal_p);
                //p_Socket.Listen(32);
                //p_Socket.BeginAccept(new AsyncCallback(onClientConnect_Policy), null);
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message);
            }
        }
        // This is the call back function, which will be invoked when a client is connected
        private void OnClientConnect(IAsyncResult asyn)
        {
            ClientSocketData socketPacket = null;
            try
            {
                Socket workerSocket = socketClientConnect.EndAccept(asyn);
                
                //workerSocket.SendBufferSize = 0;
                //workerSocket.UseOnlyOverlappedIO
                //workerSocket.Blocking = 

                //Interlocked.Increment(m_clientCount);

                //Add client socket to list
                socketPacket = new ClientSocketData(workerSocket);

                lock (clientSockets)
                {
                    this.clientSockets.Add(socketPacket);
                }
                
                //Start Waiting for data
                WaitForClientData(socketPacket);
                //main socket can go back to listening for connections
                socketClientConnect.BeginAccept(new AsyncCallback(OnClientConnect), null);
                
                this.Invoke((Action)updateControls);
            }
            catch (ObjectDisposedException)
            {
                if (socketPacket != null)
                    this.closeClientSocket(socketPacket);

                System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
            }
            catch (SocketException se)
            {
                if (socketPacket != null)
                    this.closeClientSocket(socketPacket);

                MessageBox.Show(se.Message);
            }
        }

        private string tryGetClientVersion(XmlDocument xml)
        {
            try
            {
                return xml.FirstChild.Attributes["clientversion"].Value.ToString();
            }
            catch
            {
                return "";
            }
        }

        private void Button_StopClientListening_Click(object sender, EventArgs e)
        {
            if (socketClientConnect != null)
            {
                socketClientConnect.Close();
                this.socketClientConnectListening = false;
            }

            this.Invoke((Action)updateControls);
        }
    }
}
